package com.huangc.cn.rainbow.task;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.huangc.cn.rainbow.feign.CollectDataFeign;
import com.huangc.cn.rainbow.model.CollectDataDto;
import com.huangc.cn.rainbow.spring.SpringContextHolder;
import com.huangc.cn.rainbow.util.AppRandom;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;

/**
 * @author huangc
 */
@Slf4j
public class UploadTask implements Runnable {

    private LocalDate date;

    private Long time;

    private Random random = new Random();

    private CollectDataFeign dataFeign;

    private String province;

    private String city;

    private String deviceId;

    private String loginId;

    private String version;

    private String appId;

    private String channel;

    private String model;

    private String band;

    private String OSType;

    private String sessionId;

    private String distinctId;

    private String url;

    private String h_url;

    private String domain;

    private String networktype;

    private int statusCode;

    private int errorCode;

    private String processName;

    private String errorDetail;
    //运营商
    private String carrier;

    //传输速率
    private String transRate;

    private String name;

    private String affiliation;

    private String age;

    private String sex;

    private String phone_num;

    private String customer_number;



    private boolean is_first_day = true;


    public UploadTask(String date) {
        this.date = LocalDate.parse(date);
        dataFeign = SpringContextHolder.getBean(CollectDataFeign.class);
    }

    @Override
    public void run() {
        int visitors = random.nextInt(10);
        log.info("现在开始模拟" + date.toString() + "的数据!将会进行" + visitors + "轮数据模拟!");

        for(int i = 0; i < visitors; i++) {
            log.info("现在开始模拟" + date.toString() + "的第" + i +"的数据!");

            int times = random.nextInt(5);

            province = AppRandom.getProvince();
            city = AppRandom.getCity(province);
            deviceId = AppRandom.getDeviceId();
//            deviceId = "88fbf16c3cer35688";
            loginId=AppRandom.getLoginId();
            appId = AppRandom.getAppId();
            version = AppRandom.getVersion();
//            version = "1.0.1";
            channel = AppRandom.getChannel();
//            channel = "华为商店";
            distinctId = AppRandom.getDistinctId();
            url=AppRandom.getUrl();
            h_url=url;
            domain=getDomain(url);
            networktype=AppRandom.getNetworktype();
            statusCode=AppRandom.getStatusCode();
            errorCode=AppRandom.getErrorCode();
            processName=AppRandom.getProcessName();
            errorDetail=AppRandom.getErrorDetail();
            carrier=AppRandom.getCarrier();
            name=AppRandom.getName();
            sex=AppRandom.getSex();
            age=AppRandom.getAge();
            affiliation=AppRandom.getAffiliation();
            phone_num=AppRandom.getPhone_num();
            customer_number=AppRandom.getCustomer_number();
            boolean accountFlag = random.nextBoolean();
            if(accountFlag) {
                distinctId = deviceId;
            }

            for(int j = 0; j < times; j++) {
                if(channel.equals("appStore")){
                    OSType="iOS";
                    model="One Plus 7";
                    band="Apple";
                }else {
                    OSType="Android";
                    model = AppRandom.getModel();
                    band=AppRandom.getBand();
                }
                sessionId = AppRandom.getSessionId();
                List<CollectDataDto> list = new ArrayList<>();
                CollectDataDto appStartData = appStart();
                list.add(appStartData);

                int cyc = random.nextInt(10);
                for(int z = 0; z < cyc; z++) {
                    String event = AppRandom.getEvent();

                    CollectDataDto data = new CollectDataDto();
                    time = time + random.nextInt(1000 * 60);
                    data.setApp_id(appId);
                    data.set_track_id(random.nextLong());
//                    data.set_track_id(random.nextInt(10000));
                    data.setTime(time);
                    data.set_flush_time(time);
                    data.setDistinct_id(distinctId);
                    data.setType("track");
                    data.setEvent(event);
                    data.setLib(lib());
                    data.setProperties(properties());
                    data.setName(name);
                    data.setAge(age);
                    data.setAffiliation(affiliation);
                    data.setSex(sex);
                    data.setCustomer_number(customer_number);
                    data.setPhone_num(phone_num);
                    if(random.nextInt(10)<4){
                        data.setLogin_id(loginId);
                    }

                    if(event.equals("$AppViewPause")) {
                        data.getProperties().put("event_duration", String.valueOf(random.nextDouble()*600));
                        data.getProperties().put("$screen_name", AppRandom.getPage());
                        data.getProperties().put("$ref_screen_name", AppRandom.getRefPage());
                    }
                    if(event.equals("$AppViewScreen")){
                        data.getProperties().put("$screen_name", AppRandom.getPage());
                        data.getProperties().put("$ref_screen_name", AppRandom.getRefPage());
                    }
                    if(event.equals("$SignUp")){
                        data.setLogin_id(loginId);
                    }
                    if(event.equals("#transfer_commit")){
                        data.getProperties().put("money",random.nextInt(1000));
                    }
                    if(event.equals("AppCrashed")){
                        data.getProperties().put("app_crashed_reason",AppRandom.getCrashedReason());
                    }
                    if(event.equals("AppFreezing")){
                        if(OSType.equals("Android")){
                            data.getProperties().put("app_freezing_reason",AppRandom.getAndroidFreezingReason());
                        }else {
                            //如果为iOS卡顿事件先传卡顿原因，
                            //系统时间作为卡顿原因装配的key值
                            Long time=System.currentTimeMillis();
                            String jsonStr=AppRandom.getIosFreezingReason();
//                            JSONArray jsonArray=JSONUtil.parseArray(jsonStr);

                            JSONArray jsonArray = JSON.parseArray(jsonStr);
                            jsonArray.set(2,time);
//                            dataFeign.collectFreezingReason(jsonArray);
                            data.getProperties().put("app_freezing_reason",time);
                        }

                    }
                    if(event.equals("$AppNet")){
                        data.getProperties().put("$url",url);
                        data.getProperties().put("$domain",domain);
                        data.getProperties().put("$sentBytes",random.nextInt(1000));
                        data.getProperties().put("$receivedBytes",random.nextInt(10000));
                        data.getProperties().put("$startTime",time);
                        data.getProperties().put("$networktype",networktype);
                        data.getProperties().put("$statusCode",statusCode);
                        data.getProperties().put("$errorCode",errorCode);
                        data.getProperties().put("$processName",processName);
                        data.getProperties().put("$threadId",random.nextInt(1000));
                        data.getProperties().put("$errorType",random.nextInt(3));
                        data.getProperties().put("$errorDetail",errorDetail);
                        data.getProperties().put("$totalTime",random.nextInt(10000));
                        data.getProperties().put("$carrier",carrier);
                        data.getProperties().put("$transRate",random.nextInt(10000));
                    }
                    if(event.equals("$AppStartupTime")){
                        data.getProperties().put("$startup_time",String.valueOf(random.nextDouble()*10));
                    }
                    if(event.equals("$AppWebLoadTime")){
                        data.getProperties().put("$loadTime",String.valueOf(random.nextDouble()*10));
                        data.getProperties().put("$h5_url",h_url);
                    }

                    list.add(data);
                }
                CollectDataDto existData = appExist();
                list.add(existData);
                dataFeign.collect(list);
            }
        }
    }

    /**
     * app启动事件数据
     * @return
     */
    private CollectDataDto appStart() {
        CollectDataDto data = new CollectDataDto();
        data.set_track_id(random.nextLong());

//        data.set_track_id(random.nextInt(10000));

        time = date.atStartOfDay().atZone(ZoneId.systemDefault()).toEpochSecond() * 1000 + random.nextInt(20 * 60 * 60 * 1000);

        data.setTime(time);
        data.set_flush_time(time);
        data.setApp_id(appId);
        data.setType("track");
        data.setEvent("$AppStart");
        data.setDistinct_id(distinctId);

        data.setLib(lib());
        data.setProperties(properties());

        data.setName(name);
        data.setAge(age);
        data.setAffiliation(affiliation);
        data.setSex(sex);
        data.setCustomer_number(customer_number);
        data.setPhone_num(phone_num);

        return data;
    }

    private CollectDataDto appExist() {
        CollectDataDto data = new CollectDataDto();
        data.set_track_id(random.nextLong());
//        data.set_track_id(random.nextInt(100000));
        time = time + random.nextInt(1000 * 60);
        data.setApp_id(appId);
        data.setTime(time);
        data.set_flush_time(time);
        data.setEvent("$AppEnd");
        data.setType("track");
        data.setDistinct_id(distinctId);

        data.setLib(lib());
        data.setProperties(properties());
        data.getProperties().put("event_duration", String.valueOf(random.nextDouble()*500));
        data.getProperties().put("$screen_name", AppRandom.getPage());
        data.getProperties().put("$ref_screen_name", AppRandom.getRefPage());

        data.setName(name);
        data.setAge(age);
        data.setAffiliation(affiliation);
        data.setSex(sex);
        data.setCustomer_number(customer_number);
        data.setPhone_num(phone_num);

        return data;
    }

    private Map lib() {
        Map<String, String> lib = new HashMap<>(5);
        lib.put("$lib", OSType);
        lib.put("$lib_version", "3.2.6");
        lib.put("$app_version", version);
        lib.put("$lib_method", "code");
        lib.put("$lib_detail", "com.sensorsdata.analytics.android.sdk.SensorsDataAPI##trackEvent##SensorsDataAPI.java##3112");
        return lib;
    }

    private Map properties() {
        Map<String, Object> properties = new HashMap<>();
        properties.put("$os_version", "9");
        properties.put("$cpu_num", 8);
        properties.put("$city", city);
        properties.put("$model", model);
        properties.put("$band",band);
        properties.put("$os", OSType);
        properties.put("$pixel", "720*1440");
        properties.put("$screen_width", 720);
        properties.put("$screen_height", 1440);
        properties.put("$app_version", version);
        properties.put("$lib", OSType);
        properties.put("$platform", OSType);
        properties.put("$device_id", deviceId);
        properties.put("$os_language", "zh-CN");
        properties.put("$lib_version", "4.1.2");
        properties.put("$total_mem", 2964135936L);
        properties.put("$province", province);
        properties.put("$timezone_offset", -480);
        properties.put("$app_id", appId);
        properties.put("$sessionId", sessionId);
        properties.put("$channel", channel);
        properties.put("customer_number",customer_number);
        properties.put("$name",name);
        properties.put("affiliation",affiliation);
        properties.put("age",age);
        properties.put("sex",sex);
        properties.put("phone_num",phone_num);

        properties.put("$is_first_day", is_first_day);
        is_first_day = false;

//        properties.put("$screen_name", AppRandom.getPage());
//        properties.put("$ref_screen_name", AppRandom.getPage());

        return properties;
    }

    /**
     * 获取域名
     * @param url
     * @return
     */
    private String getDomain(String url){
        //去除http和https前缀
        url = url.replace("http://","").replace("https://","");
        //按‘/’分隔，取第一个，获取域名
        String [] arr = url.split("/");
        String domain=arr[0];
        return domain;
    }


}
